package cn.vconinfo.base.utils;

import com.alibaba.fastjson.JSON;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.slf4j.helpers.MessageFormatter;
import org.springframework.util.StringUtils;

import javax.annotation.Nonnull;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.NotNull;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.UUID;
import java.util.function.Function;

public class CommonUtils {
    private static final String SEPERATOR = ":";
    private static final char UNDERLINE = '_';

    public CommonUtils() {
    }

    public static String format(@Nonnull String message, Object... args) {
        return MessageFormatter.arrayFormat(message, args).getMessage();
    }

    public static String beanToJson(@Nonnull Object obj) {
        return JSON.toJSONString(obj);
    }

    public static <T> T jsonToBean(@Nonnull String json, Class<T> cls) {
        return JSON.parseObject(json, cls);
    }

    public static String getUuid() {
        return UUID.randomUUID().toString().replace("-", "").toUpperCase();
    }

    public static String getRequestJsonParam(HttpServletRequest request) throws IOException {
        ByteArrayOutputStream result = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        ServletInputStream inputStream = request.getInputStream();

        int length;
        while((length = inputStream.read(buffer)) != -1) {
            result.write(buffer, 0, length);
        }

        return String.valueOf(result);
    }

    public static String produceKey(String... keys) {
        StringBuilder key = new StringBuilder();
        if (keys.length == 1) {
            key = new StringBuilder(keys[0]);
        } else {
            for(int i = 0; i < keys.length - 1; ++i) {
                key.append(keys[i]).append(":");
            }

            key.append(keys[keys.length - 1]);
        }

        return key.toString();
    }

    public static String camelToUnderline(@Nonnull String param) {
        int len = param.length();
        StringBuilder sb = new StringBuilder(len);

        for(int i = 0; i < len; ++i) {
            char c = param.charAt(i);
            if (Character.isUpperCase(c) && i > 0) {
                sb.append('_');
            }

            sb.append(Character.toLowerCase(c));
        }

        return sb.toString();
    }

    public static String underlineToCamel(@Nonnull String param) {
        int len = param.length();
        StringBuilder sb = new StringBuilder(len);

        for(int i = 0; i < len; ++i) {
            char c = param.charAt(i);
            if (c == '_') {
                ++i;
                if (i < len) {
                    sb.append(Character.toUpperCase(param.charAt(i)));
                }
            } else {
                sb.append(c);
            }
        }

        return sb.toString();
    }

    /** @deprecated */
    @Deprecated
    public static String encodeParameter(@NotNull String param) {
        return StringUtils.isEmpty(param) ? param : param.replaceAll("%", "\\\\%").replaceAll("_", "\\\\_").replaceAll("\\\\", "\\\\\\\\");
    }

    public static String encodeParam(@NotNull String param) {
        if (StringUtils.isEmpty(param)) {
            return param;
        } else {
            return param.contains("\\") ? param.replaceAll("\\\\", "\\\\\\\\") : param.replaceAll("%", "\\\\%").replaceAll("_", "\\\\_");
        }
    }

    public static <T> T newInstance(@Nonnull Class<T> tClass) {
        try {
            T t = tClass.newInstance();
            return t;
        } catch (IllegalAccessException | InstantiationException var3) {
            var3.printStackTrace();
            throw new RuntimeException(format("Create new instance of {} failed: {}", tClass, var3.getMessage()));
        }
    }

    public static boolean isAllEmpty(Object... values) {
        if (ArrayUtils.isEmpty(values)) {
            return true;
        } else {
            Object[] var1 = values;
            int var2 = values.length;

            for(int var3 = 0; var3 < var2; ++var3) {
                Object val = var1[var3];
                if (ObjectUtils.isNotEmpty(val)) {
                    return false;
                }
            }

            return true;
        }
    }

    public static boolean isAllNotEmpty(Object... values) {
        if (ArrayUtils.isEmpty(values)) {
            return false;
        } else {
            Object[] var1 = values;
            int var2 = values.length;

            for(int var3 = 0; var3 < var2; ++var3) {
                Object val = var1[var3];
                if (ObjectUtils.isEmpty(val)) {
                    return false;
                }
            }

            return true;
        }
    }

//    public static <T, V> V notNullGet(T obj, @Nonnull Function<T, V> value) {
//        return notNullGet(obj, value, (Object)null);
//    }

    public static <T, V> V notNullGet(T obj, @Nonnull Function<T, V> value, V defaultValue) {
        return obj == null ? defaultValue : value.apply(obj);
    }

}
